﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Controls.Maps;
using System.Threading;
using Microsoft.Devices;
using System.Device.Location;
using System.Device;
using Microsoft.Phone.Tasks;
using Microsoft.Phone.TaskModel;
using PublicClass;
//using Windows.Devices.Geolocation;

namespace SimpleRadar
{
    public partial class MainPage : PhoneApplicationPage
    {
        #region GPSWatch&Route
        // Khai báo biến quan sát GPS
        GeoCoordinateWatcher mywatcher;
        Popup popup = new Popup();
        BingMapEx bingEx = new BingMapEx();
        #endregion

        #region Maplayer để hiển thị
        MapLayer FindPushpin = new MapLayer();
        MapLayer radarSearch = new MapLayer();
        MapLayer Routelayer = new MapLayer();
        #endregion

        #region LayerDrawRadar
        // Vòng tròn radar
        MapPolygon bigCircle = new MapPolygon();
        // Đường thẳng quay quanh tâm hiện tại
        MapPolyline line = new MapPolyline();
        //Đánh dấu vị trị của mình bằng Pushpin
        Pushpin myLocationPushpin = new Pushpin();
        // Thực hiện việc vẽ kim đồng hồ xoay xoay
        Thread RadarScan;
        // Biến góc chạy quang vòng tròn
        double angle = 0;
        #endregion

        //Pushpin OtherPushpin = new Pushpin();

        public MainPage()
        {
            InitializeComponent();
            ///Settings map
            InitializeLayer();
            InitializeMap();// Khởi tạo bản đồ hiển thị ....
            InitializeSetting(); // Khởi tạo thông tin từ các thiết lập của hệ thống
            InitializeGPS();// Khởi động chức năng GPS watch
            InitializeRadar();// Khởi tạo hình dạng Radar

           // OtherPushpin.Create("OtherPushpin", new GeoCoordinate(16.4620 , 107.5555), "Có người ở đây");
        }

        #region Khởi tạo thông tin và dữ liệu
        private void InitializeSetting()
        {
            // Sử lý thiết lập chế độ hiển thị từ bản đồ
            if (Global.setting.AreaView == true)

                map1.Mode = new AerialMode(true);
            else
                map1.Mode = new RoadMode();

            Global.setting.UpdateSettingCompleted += (s, e) =>
            {
                if (e.Result.AreaView == true) // Chế độ hiển thị của bản đồ

                    map1.Mode = new AerialMode(true);
                else
                    map1.Mode = new RoadMode();

                UpdateRadarCircle(mywatcher.Position.Location, Global.setting.RadaZoom);
            };
        }
        private void InitializeLayer()
        {
            // Khởi tạo thông tin của Line vẽ
            line.Locations = new LocationCollection();
            line.Stroke = new SolidColorBrush(Colors.Green);
            line.Opacity = 0.7;
            line.StrokeThickness = 5;
            // Khởi tạo thông tin vòng tròn
            bigCircle.Stroke = new SolidColorBrush(Color.FromArgb(100, 255, 0, 0));
            bigCircle.Fill = new SolidColorBrush(Color.FromArgb(100, 42, 180, 58));
            bigCircle.StrokeThickness = 10;
            bigCircle.Opacity = 0.8;
            bigCircle.BorderBrush = new SolidColorBrush(Colors.Green);
            // Khởi tạo Pushpin vị trí của mình
            myLocationPushpin.Tag = "locationPushpin";
            myLocationPushpin.Content = "Bạn đang ở đây";
        }
        private void InitializeMap()
        {
            map1.ZoomBarVisibility = Visibility.Visible; // Bật thanh Zoom
            map1.LogoVisibility = Visibility.Collapsed; // Tắt logo bingmap
            map1.CopyrightVisibility = Visibility.Collapsed;// Tắt dòng CopyRight của Bingmap
            // Thiết lập vị trí hiển thị ncuar bản đồ
            map1.Center = new GeoCoordinate(16.4575 , 107.5840);
            map1.SetView(map1.Center, 15);
            // Thiết lập tỉ lệ Zoom của map            
            map1.ZoomLevel = 15;
            // Add các Control con vào bản đồ
            map1.Children.Clear();
            map1.Children.Add(bigCircle);
            map1.Children.Add(line);
            map1.Children.Add(myLocationPushpin);
            //map1.Children.Add(OtherPushpin);
            map1.Children.Add(FindPushpin);
        }
        private void InitializeGPS()
        {
            if (mywatcher == null)
            {
                // Khởi tạo đọc GPRS
                mywatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
                // tốc độ chuyển hình
                mywatcher.MovementThreshold = 20;
                // Thực hiện khi thay đổi trạng thái của GPS watch
                mywatcher.StatusChanged += (s, e) =>
                {
                    switch (e.Status)
                    {
                        case GeoPositionStatus.Disabled:
                            MessageBox.Show("Bạn chưa bật GPS");
                            break;
                        case GeoPositionStatus.NoData:
                            MessageBox.Show("Không thể lấy vị trí hiện tại của bản");
                            break;
                    }
                };
                // Thực hiện khi thay đổi địa điểm , cụ thể là nếu bạn di chuyển
                mywatcher.PositionChanged += (s, e) =>
                {
                    if (e.Position.Location.IsUnknown)
                    {
                        MessageBox.Show("Xin vui long chờ ! Đang tìm kiếm địa điểm của bạn....");
                    }
                    this.map1.Center = e.Position.Location;

                    myLocationPushpin.Location = mywatcher.Position.Location;
                    // Vẽ lại vòng tròn ngoài của Radar
                    UpdateRadarCircle(e.Position.Location, Global.setting.RadaZoom);
                };
            }
            //Bật chức năng watcher GPRS
            mywatcher.Start();
            
        }
        private void InitializeRadar()
        {
            // Khởi tạo vòng xoay kim đồng hồ 
            RadarScan = new Thread((ThreadStart)delegate()
            {

                while (true)
                {
                    Thread.Sleep(30);

                    Dispatcher.BeginInvoke(() => DrawLineRadar(mywatcher.Position.Location, Global.setting.RadaZoom, angle));

                    angle += 1;
                    if (angle >= 360) angle = 0;
                }
            });

            RadarScan.Start();
        }
        #endregion

        #region Vẽ vòng tròn và đường thằng của Radar
        private void UpdateRadarCircle(GeoCoordinate location, double Zoom)
        {
            BingMapEx obj = new BingMapEx();

            obj.FindByLocationCompleted += (s, e) =>
            {
                myLocationPushpin.Content = e.Result;
            };
            obj.FindByLocation(location.Longitude, location.Latitude);
            
            if (location == null)

                return;

            bigCircle.Visibility = Visibility.Visible;
            bigCircle.Locations = new LocationCollection();
            bigCircle.DrawCircler(location, Zoom);        
        }
        void DrawLineRadar(GeoCoordinate location, double Zoom, double angle)
        {
            if (location == null) return;
            line.Locations.Clear();
            var earthRadius = 6371;
            var lat = mywatcher.Position.Location.Latitude * Math.PI / 180.0; //radians 
            var lon = mywatcher.Position.Location.Longitude * Math.PI / 180.0; //radians 
            var d = mywatcher.Position.Location.HorizontalAccuracy / Zoom / earthRadius; // d = angular distance covered on earths surface 

            var brng = angle * Math.PI / 180.0; //radians 
            var latRadians = Math.Asin(Math.Sin(lat) * Math.Cos(d) + Math.Cos(lat) * Math.Sin(d) * Math.Cos(brng));
            var lngRadians = lon + Math.Atan2(Math.Sin(brng) * Math.Sin(d) * Math.Cos(lat), Math.Cos(d) - Math.Sin(lat) * Math.Sin(latRadians));

            var pt = new GeoCoordinate(180.0 * latRadians / Math.PI, 180.0 * lngRadians / Math.PI);
            line.DrawLine(mywatcher.Position.Location, pt);

            
        }
        private void ShowPushpinContain(List<Pushpin> Pushpins)
        {
            foreach(Pushpin pushpin in Pushpins)
            {
                if (bigCircle.Contains(pushpin.Location))
                {
                    if (pushpin.Template == this.Resources["PinTemplate"] as ControlTemplate)

                        pushpin.Template = this.Resources["PinTemplate2"] as ControlTemplate;
                    else
                        pushpin.Template = this.Resources["PinTemplate"] as ControlTemplate;

                    pushpin.Visibility = Visibility.Visible;
                }
                else
                    pushpin.Visibility = Visibility.Collapsed;
            }
        }
        #endregion

        private GeoCoordinate GetPoint(GeoCoordinate location, double Zoom, double angle)
        {
            if (location == null) return null;
            var earthRadius = 6371;
            var lat = mywatcher.Position.Location.Latitude * Math.PI / 180.0; //radians 
            var lon = mywatcher.Position.Location.Longitude * Math.PI / 180.0; //radians 
            var d = mywatcher.Position.Location.HorizontalAccuracy / Zoom / earthRadius; // d = angular distance covered on earths surface 

            var brng = angle * Math.PI / 180.0; //radians 
            var latRadians = Math.Asin(Math.Sin(lat) * Math.Cos(d) + Math.Cos(lat) * Math.Sin(d) * Math.Cos(brng));
            var lngRadians = lon + Math.Atan2(Math.Sin(brng) * Math.Sin(d) * Math.Cos(lat), Math.Cos(d) - Math.Sin(lat) * Math.Sin(latRadians));

            var pt = new GeoCoordinate(180.0 * latRadians / Math.PI, 180.0 * lngRadians / Math.PI);

            return pt;
        }

        #region Event của ApplicationBar
        private void ApplicationBarMenuItem_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri(@"/GUI/PageSettings.xaml",UriKind.Relative));     
        }

        private void ApplicationBarMenuItem_Click_1(object sender, EventArgs e)
        {
        }

        private void btnMe_Click(object sender, EventArgs e)
        {
            map1.Center = mywatcher.Position.Location;
        }

        private void btnRoute_Click(object sender, EventArgs e)
        {
            GUI.FindRouteUI findUI=new GUI.FindRouteUI();

            popup.Child = findUI;

            popup.IsOpen = true;

            findUI.background.Tap += (s, args) =>
            {
                popup.IsOpen = false;
            };
            findUI.btnCancel.Click += (s, args) =>
            {
                popup.IsOpen = false;
            };


            //if (mywatcher != null && OtherPushpin != null && map1 != null)
            //{
            //    List<GeoCoordinate> locations = new List<GeoCoordinate>();
            //    locations.Add(mywatcher.Position.Location);
            //    locations.Add(OtherPushpin.Location);
            //    BingMapEx mapex=new BingMapEx();
            //    mapex.GetRouteLine(map1, locations);
            //    mapex.GetRouteCompleted += (s, args) =>
            //    {
            //        map1.Children.Add(args.Result);
            //        map1.SetView(LocationRect.CreateLocationRect(locations));
            //    };
            //}
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            // Khai báo thông tin việc tìm kiếm địa điểm
           
            GUI.SearchUI UI=new GUI.SearchUI();

            // THiết lập cho BingEx
            bingEx.FindByAddressCompleted+=(s,args)=>
            {
                if (args.Pushpins.Count > 0)
                {
                    FindPushpin.Children.Clear();
                    for (int i = 0; i < args.Pushpins.Count; i++)
                    {
                        args.Pushpins[i].Content = "vị trí " + (i+1).ToString();
                        FindPushpin.Children.Add(args.Pushpins[i]);
                    }
                }
                else
                    MessageBox.Show(args.Messager);
            };
            // Thiết lập cho UI
            UI.background.Tap += (s, args) =>
            {
                popup.IsOpen = false;
            };
            UI.btnCancel.Tap += (s, args) =>
            {
                popup.IsOpen = false;
            };
            UI.btnOk.Tap += (s, args) =>
            {
                if (UI.txtInput.Text != "")
                {
                    bingEx.FindByAddress(UI.txtInput.Text);
                }
                popup.IsOpen = false;
            };
            popup.Child = UI;
            popup.IsOpen = true;
        }

        #endregion
    }
}